<template>
	<cl-crud ref="Crud">
		<cl-row>
			<!-- 刷新按钮 -->
			<cl-refresh-btn />
			<!-- 新增按钮 -->
			<cl-add-btn />
			<!-- 删除按钮 -->
			<!-- <cl-multi-delete-btn /> -->
			<cl-export-btn :columns="Table?.columns" />
			<cl-flex1 />
			<!-- 条件搜索 -->
			<cl-search ref="Search" />
		</cl-row>

		<cl-row>
			<!-- 数据表格 -->
			<cl-table ref="Table">
				<!-- 插槽的渲染方式 #[component.name] -->
				<template #slot-invite-btn="{ scope }">
					<el-button
						type="success"
						@click="
							() => {
								showInvitePoster(scope.row);
							}
						"
						>邀请海报</el-button
					>
				</template>
				<template #slot-appoint-btn="{ scope }">
					<el-button
						type="success"
						@click="
							() => {
								showAppointDialog(scope.row.id);
							}
						"
						>预约</el-button
					>
				</template>
				<template #slot-change-btn="{ scope }">
					<el-button
						type="success"
						@click="
							() => {
								showAppointDialog(scope.row.id);
							}
						"
						>改约</el-button
					>
				</template>
				<template #slot-cancle-btn="{ scope }">
					<el-button
						type="danger"
						@click="
							() => {
								cancleAppoint(scope.row.id);
							}
						"
						>取消</el-button
					>
				</template>
			</cl-table>
		</cl-row>

		<cl-row>
			<cl-flex1 />
			<!-- 分页控件 -->
			<cl-pagination />
		</cl-row>

		<!-- 新增、编辑 -->
		<cl-upsert ref="upsertRef" />
	</cl-crud>
	<cl-dialog title="邀请海报" v-model="invitePosterDialogVisible" width="400px">
		<div style="text-align: center; display: flex; flex-direction: column; align-items: center">
			<div class="qrcode-container" style="margin: 20px 0">
				<img :src="qrCodeUrl" alt="二维码" style="width: 270px; height: 447.5px" />
			</div>
			<el-button type="primary" @click="saveInvitePoster">保存海报</el-button>
		</div>
	</cl-dialog>
	<!--预约弹窗-->
	<week-appoint-dialog
		v-model="appointDialogVisible"
		:student-id="currentStudentId"
		@success="refresh"
	/>
</template>

<script lang="ts" setup>
defineOptions({
	name: 'student-student'
});

import { useCrud, useTable, useUpsert, useSearch } from '@cool-vue/crud';
import { useCool } from '/@/cool';
import { useI18n } from 'vue-i18n';
import { reactive, ref, watch, nextTick } from 'vue';
import { useDict } from '/$/dict';
import { ElMessage, ElMessageBox } from 'element-plus';
import { useRoute } from 'vue-router';
import { useBase } from '/$/base';
import QRCode from 'qrcode';
import WeekAppointDialog from '../components/WeekAppointDialog.vue';
import SelectSubway from '../components/select-subway.vue';

const { service, setRefs, refs } = useCool();
const { t } = useI18n();
const route = useRoute();
const { user } = useBase();
const appointDialogVisible = ref(false);
const currentStudentId = ref(0);

// 选项
const options = reactive({
	appointmentStatus: [
		{ label: t('已预约'), value: 0 },
		{ label: t('已到店'), value: 1 },
		{ label: t('已改约'), value: 2 },
		{ label: t('已过期'), value: 3 },
		{ label: t('已取消'), value: 4 }
	],
	gender: [
		{ label: t('男'), value: 0 },
		{ label: t('女'), value: 1 }
		// { label: t('未知'), value: 2 }
	],
	salesList: []
});
const { dict } = useDict();
const disabled = ref(true);
// 添加 upsertRef
// const upsertRef = ref();
// cl-upsert
const upsertRef = useUpsert({
	items: [
		{
			label: t('会员卡号'),
			prop: 'studentNo',
			component: {
				name: 'el-input',
				props: {
					clearable: true,
					placeholder: '新增时自动生成',
					disabled
				}
			},
			required: true
		},
		{
			label: t('姓名'),
			prop: 'name',
			component: { name: 'el-input', props: { clearable: true } },
			span: 8,
			required: true
		},
		{
			label: t('手机号'),
			prop: 'phone',
			component: { name: 'el-input', props: { clearable: true } },
			span: 8,
			required: true
		},
		{
			label: t('用户类型'),
			prop: 'userType',
			component: {
				name: 'el-select',
				options: dict.get('userType')
			},
			span: 8
		},
		{
			label: t('性别'),
			prop: 'gender',
			component: { name: 'el-radio-group', options: options.gender },
			value: '',
			span: 8,
			required: true
		},
		{
			label: t('生日'),
			prop: 'birthday',
			component: {
				name: 'el-date-picker',
				props: { type: 'date', valueFormat: 'YYYY-MM-DD' }
			},
			span: 8,
			required: true
		},

		{
			label: t('微信昵称'),
			prop: 'wechatNickName',
			component: { name: 'el-input', props: { clearable: true } },
			span: 8
		},
		{
			label: t('左眼度数'),
			prop: 'leftEye',
			hook: 'number',
			component: { name: 'el-input-number' },
			span: 8
		},
		{
			label: t('右眼度数'),
			prop: 'rightEye',
			hook: 'number',
			component: { name: 'el-input-number' },
			span: 8
		},
		{
			label: t('项目'),
			prop: 'project',
			component: {
				name: 'cl-select',
				props: {
					tree: true,
					checkStrictly: true,
					options: dict.get('Project')
				}
			},
			span: 8
		},
		{
			label: t('来源'),
			prop: 'source',
			component: {
				name: 'el-select',
				options: dict.get('Source')
			},
			span: 8
		},
		{
			label: t('所属门店'),
			prop: 'shop',
			component: {
				name: 'el-select',
				options: dict.get('Shop')
			},
			span: 8
		},
		{
			label: t('销售'),
			prop: 'sales',
			component: { name: 'el-select', options: options.salesList },
			span: 8,
			ref: setRefs('sales'),
			default: user.info?.id
		},
		{
			label: t('跟进状态'),
			prop: 'flowStatus',
			component: {
				name: 'el-select',
				options: dict.get('flowStatus')
			},
			span: 12
		},
		{
			label: t('入组'),
			prop: 'inGroup',
			component: {
				name: 'cl-select',
				props: {
					tree: true,
					checkStrictly: true,
					options: dict.get('inGroup')
				}
			},
			span: 12
		},
		{
			prop: 'subway',
			component: {
				vm: SelectSubway,
			},
		},
		{
			label: t('备注'),
			prop: 'remark',
			component: {
				name: 'el-input',
				props: { type: 'textarea', rows: 4 }
			}
		}
	],
	onOpen() {
		if (!upsertRef.value.form.studentNo) {
			upsertRef.value.form.studentNo = new Date().getTime().toString().slice(-10);
		}
		service.base.sys.user.getSelectList().then((res: any) => {
			if (res) {
				const salesItem = upsertRef.value.items.find(item => item.prop === 'sales');
				console.log('salesList', res, salesItem);
				salesItem.component.options = res;
			}
		});
	},
	async onSubmit(data, { done, close, next }) {
		next({
			...data,
			sales: data.sales || user.info?.id
		});
	}
});

// cl-table
const Table = useTable({
	columns: [
		{ type: 'selection', hidden: true },

		{ label: t('预约状态'), prop: 'appointmentText', minWidth: 140 },
		{ label: t('预约门店'), prop: 'appointmentShop', minWidth: 140 },
		{ label: t('最近预约日期'), prop: 'appointmentDate', minWidth: 140 },
		{ label: t('ID'), prop: 'id', minWidth: 60 },
		{ label: t('姓名'), prop: 'name', minWidth: 140 },
		{ label: t('手机号'), prop: 'phone', minWidth: 140 },
		{
			label: t('性别'),
			prop: 'gender',
			minWidth: 120,
			dict: options.gender
		},
		{
			label: t('生日'),
			prop: 'birthday',
			minWidth: 140,
			sortable: 'custom',
			component: {
				name: 'cl-date-text',
				props: { format: 'YYYY-MM-DD' }
			}
		},
		{ label: t('来源'), prop: 'source', dict: dict.get('Source') },
		{ label: t('所属门店'), prop: 'shop', dict: dict.get('Shop') },
		{ label: t('销售'), prop: 'salesName' },
		{
			label: t('项目'),
			prop: 'project',
			dict: dict.get('Project'),
			minWidth: 140
		},
		{
			label: t('入组'),
			prop: 'inGroup',
			dict: dict.get('inGroup'),
			minWidth: 140
		},
		{ label: t('地铁站'), prop: 'subway', showOverflowTooltip: true, minWidth: 120 },
		{ label: t('备注'), prop: 'remark', showOverflowTooltip: true },
		{ label: t('预约状态'), prop: 'appointmentTextShop', minWidth: 80, hidden: true },
		{ label: t('预约门店'), prop: 'appointmentShopShop', minWidth: 80, hidden: true },
		{ label: t('最近预约日期'), prop: 'appointmentDateShop', minWidth: 100, hidden: true },
		{
			type: 'op',
			buttons: ['slot-invite-btn', 'slot-appoint-btn', 'edit'],
			width: 300
		}
	]
});

// cl-search
const Search = useSearch({
	items: [
		{
			prop: 'appointmentStatus',
			component: {
				name: 'cl-select',
				props: { options: options.appointmentStatus, placeholder: '预约状态' }
			}
		},
		{
			prop: 'source',
			component: {
				name: 'cl-select',
				props: { options: dict.get('Source'), placeholder: '渠道' }
			}
		},
		{
			prop: 'project',
			component: {
				name: 'cl-select',
				props: {
					tree: true,
					checkStrictly: true,
					options: dict.get('Project'),
					placeholder: '项目'
				}
			}
		},
		{
			prop: 'inGroup',
			component: {
				name: 'cl-select',
				props: {
					tree: true,
					checkStrictly: true,
					options: dict.get('inGroup'),
					placeholder: '入组'
				}
			}
		},
		{
			prop: 'shopId',
			component: {
				name: 'cl-select',
				props: { options: dict.get('Shop'), placeholder: '门店' }
			}
		},
		{
			prop: 'phone',
			component: {
				name: 'el-input',
				props: { placeholder: '请输入电话' }
			}
		},
		{
			prop: 'name',
			component: {
				name: 'el-input',
				props: { placeholder: '请输入姓名' }
			}
		}
	]
});

// cl-crud
const Crud = useCrud(
	{
		service: service.student.student,
		async onRefresh(params, { next, done, render }) {
			console.log('routepath', route.path);
			if (route.path.endsWith('myStudent') || route.path.endsWith('')) {
				params.sales = user.info?.id;
				params.showAppoint = 1;
			}
			if (route.path.endsWith('flowStudent')) {
				params.sales = user.info?.id;
				params.appoint = 0;
				params.showAppoint = 1;
			}
			if (route.path.endsWith('myAppoint')) {
				params.sales = user.info?.id;
				params.appoint = 1;
				params.showAppoint = 1;
			}
			if (route.path.endsWith('seaStudent')) {
				// params.appoint = 0;
				params.flowStatus = [131];
				params.showAppoint = 1;
			}
			if (route.path.endsWith('shopStudent')) {
				params.shop = user.info?.shop;
				params.flowStatus = [134, 133];
				params.showAppoint = 1;
			}
			if (route.path.endsWith('allStudent')) {
				params.showAppoint = 1;
				params.allStudent = 1;
			}
			const { list } = await next(params);

			// 渲染数据
			render(list);
		}
	},
	app => {
		app.refresh();
	}
);

watch(
	() => route.path,
	async newPath => {
		// 刷新数据
		await Crud.value?.refresh();
		// 更新表格列配置
		if (Table.value?.columns) {
			// 正在跟进可以预约
			const appointmentTextColumn = Table.value.columns.find(
				col => col.prop === 'appointmentText'
			);
			const appointmentShopColumn = Table.value.columns.find(
				col => col.prop === 'appointmentShop'
			);
			const appointmentDateColumn = Table.value.columns.find(
				col => col.prop === 'appointmentDate'
			);
			const appointmentTextShopColumn = Table.value.columns.find(
				col => col.prop === 'appointmentTextShop'
			);
			const appointmentShopShopColumn = Table.value.columns.find(
				col => col.prop === 'appointmentShopShop'
			);
			const appointmentDateShopColumn = Table.value.columns.find(
				col => col.prop === 'appointmentDateShop'
			);

			const opColumn = Table.value.columns.find(col => col.type === 'op');
			if (newPath.endsWith('flowStudent')) {
				appointmentShopColumn ? (appointmentShopColumn.hidden = true) : '';
				appointmentDateColumn ? (appointmentDateColumn.hidden = true) : '';
				opColumn ? (opColumn.buttons = ['slot-appoint-btn', 'edit']) : '';
			}
			// 已预约，可以取消预约
			else if (newPath.endsWith('myAppoint')) {
				appointmentShopColumn ? (appointmentShopColumn.hidden = false) : '';
				appointmentDateColumn ? (appointmentDateColumn.hidden = false) : '';
				opColumn ? (opColumn.buttons = ['slot-change-btn', 'edit']) : '';
			}
			// 门店学员可以改约
			else if (newPath.endsWith('shopStudent')) {
				appointmentTextColumn ? (appointmentTextColumn.hidden = true) : '';
				appointmentShopColumn ? (appointmentShopColumn.hidden = true) : '';
				appointmentDateColumn ? (appointmentDateColumn.hidden = true) : '';
				appointmentTextShopColumn ? (appointmentTextShopColumn.hidden = false) : '';
				appointmentShopShopColumn ? (appointmentShopShopColumn.hidden = false) : '';
				appointmentDateShopColumn ? (appointmentDateShopColumn.hidden = false) : '';
				opColumn ? (opColumn.buttons = ['slot-change-btn', 'edit']) : '';
			} else if (newPath.endsWith('allStudent')) {
				appointmentShopColumn ? (appointmentShopColumn.hidden = false) : '';
				appointmentDateColumn ? (appointmentDateColumn.hidden = false) : '';
				opColumn ? (opColumn.buttons = ['slot-invite-btn', 'slot-appoint-btn', 'edit']) : '';
			} else if (newPath.endsWith('myStudent')) {
				appointmentShopColumn ? (appointmentShopColumn.hidden = false) : '';
				appointmentDateColumn ? (appointmentDateColumn.hidden = false) : '';
				opColumn
					? (opColumn.buttons = ['slot-invite-btn', 'slot-appoint-btn', 'edit'])
					: '';
			} else if (newPath.endsWith('seaStudent')) { // 公海学员
				appointmentShopColumn ? (appointmentShopColumn.hidden = false) : '';
				appointmentDateColumn ? (appointmentDateColumn.hidden = false) : '';
				opColumn
					? (opColumn.buttons = ['slot-appoint-btn', 'edit'])
					: '';
			} else {
				appointmentShopColumn ? (appointmentShopColumn.hidden = false) : '';
				appointmentDateColumn ? (appointmentDateColumn.hidden = false) : '';
				opColumn
					? (opColumn.buttons = ['slot-invite-btn', 'slot-appoint-btn', 'edit'])
					: '';
			}
		}
	},
	{ immediate: true }
);

// 添加邀请海报相关的响应式变量
const invitePosterDialogVisible = ref(false);
const inviteUrl = ref('');
const qrCodeUrl = ref('');

async function showInvitePoster(row: any) {
	inviteUrl.value = `http://fronteye.joyballet.cn/#/userInvite?sales_id=100${row.id}`;
	invitePosterDialogVisible.value = true;

	try {
		// 生成二维码
		const qrDataUrl = await QRCode.toDataURL(inviteUrl.value);
		console.log('qrDataUrl', qrDataUrl);

		// 创建 Canvas
		const canvas = document.createElement('canvas');
		const ctx = canvas.getContext('2d');

		// 设置画布大小为固定比例
		canvas.width = 1080;
		canvas.height = 1790;

		// 加载背景图
		const bgImage = new Image();
		bgImage.crossOrigin = 'anonymous';
		bgImage.src =
			'https://joyballet.oss-cn-beijing.aliyuncs.com/eyemanager/sales/invite_poster2.jpg';

		await new Promise((resolve, reject) => {
			bgImage.onload = resolve;
			bgImage.onerror = reject;
		});

		// 计算背景图绘制参数，保持比例
		const scale = Math.max(canvas.width / bgImage.width, canvas.height / bgImage.height);
		const x = (canvas.width - bgImage.width * scale) / 2;
		const y = (canvas.height - bgImage.height * scale) / 2;

		// 绘制背景图（自适应）
		ctx.drawImage(bgImage, x, y, bgImage.width * scale, bgImage.height * scale);

		// 添加ID文字
		ctx.fillStyle = '#333333';
		ctx.font = 'bold 40px Arial';
		ctx.textAlign = 'center';
		const text = `${row.id}`;
		ctx.fillText(text, canvas.width - 60, canvas.height - 20);

		// 加载二维码图片
		const qrImage = new Image();
		qrImage.src = qrDataUrl;

		await new Promise((resolve, reject) => {
			qrImage.onload = resolve;
			qrImage.onerror = reject;
		});

		// 绘制二维码
		const qrSize = 200;
		const qrX = (canvas.width - qrSize) / 2;
		const qrY = canvas.height - qrSize - 220;
		ctx.drawImage(qrImage, qrX, qrY, qrSize, qrSize);

		// 将合成后的图片转换为 base64
		qrCodeUrl.value = canvas.toDataURL('image/png');
	} catch (err) {
		console.error('生成海报失败:', err);
		ElMessage.error('生成海报失败');
	}
}

function saveInvitePoster() {
	const link = document.createElement('a');
	link.download = `邀请海报_${new Date().getTime()}.png`;
	link.href = qrCodeUrl.value;
	document.body.appendChild(link);
	link.click();
	document.body.removeChild(link);
	ElMessage({
		type: 'success',
		message: '海报已保存'
	});
}

// 刷新
function refresh(params?: any) {
	Crud.value?.refresh(params);
}

function showAppointDialog(studentId) {
	currentStudentId.value = studentId;
	appointDialogVisible.value = true;
}
</script>
<style scoped>
.appoint-item {
	margin-top: 5px;
	margin-bottom: 20px;
}
.timeList {
	margin-top: 20px;
}

.time-row {
	display: flex;
	justify-content: space-between;
	margin-bottom: 10px;
}

.time-slot {
	width: 45%;
	padding: 10px;
	text-align: center;
	border-radius: 4px;
	cursor: pointer;
	background-color: #fff;
	border: 1px solid #dcdfe6;
}

.time-slot.available {
	background-color: #e1f3d8;
	color: #67c23a;
	cursor: pointer;
}

.time-slot.available.selected {
	background-color: #fff;
	border: 1px solid #409eff;
	color: #409eff;
}

.time-slot.unavailable {
	background-color: #fde2e2;
	color: #f56c6c;
	cursor: pointer;
}

.time-slot.unavailable.selected {
	background-color: #fff;
	border: 1px solid #409eff;
	color: #409eff;
}
</style>
<style>
/* 由于 Element Plus 的对话框在 body 下，所以不能使用 scoped */
.custom-confirm-dialog .el-button--primary:not(.el-button--primary.el-button--default) {
	background-color: var(--el-button-bg-color);
	border-color: var(--el-button-border-color);
	color: var(--el-button-text-color);
}
</style>
